//
//  FlyWeight.swift
//  FlyweightPattern
//
//  Created by LY on 2017/11/5.
//  Copyright © 2017年 DesignPatterns. All rights reserved.
//

import Foundation

class FlyWeightImplement:FlyWeight{
    private let dataHandlerQueue : DispatchQueue
    var total: Int{
        return extrinsicData.values.reduce(0, { (total, cell) -> Int in
            if let intrisicCell = intrinsicData[cell.coordinate]{
                return total + intrisicCell.value
            }else{
                return total + cell.value
            }
        })
    }
    
    var count: Int{
             return self.intrinsicData.count
    }
    
    func setSunScription(index: Coordinate, value: Int?) {
        dataHandlerQueue.sync {
            if value != nil {
                intrinsicData[index] = Cell(col: index.col, row:index.row , val: value!)
            }
        }
    }
    
    func getSubScription(index: Coordinate) -> Int? {
            if let cell = self.intrinsicData[index] {
                    return cell.value
            }else{
                    return self.extrinsicData[index]?.value
            }
    }
    
    private let extrinsicData:[Coordinate:Cell]
    
    private var intrinsicData:[Coordinate:Cell]
    
    fileprivate init(extrinsicData:[Coordinate:Cell]){
        self.extrinsicData = extrinsicData
        self.intrinsicData = [Coordinate:Cell]()
        dataHandlerQueue = DispatchQueue(label: "FlyWeight")
    }
}

class FlyweightFactory{
    class func createFlyWeight() -> FlyWeight{
        return FlyWeightImplement(extrinsicData: extrinsicData)
    }
    
    private class var extrinsicData:[Coordinate:Cell]{
        var result = [(Coordinate,Cell)]()
        let letter:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        var stringIndex = letter.startIndex
        let rows = 50
        repeat {
            let colLetter = letter[stringIndex]
            stringIndex = letter.index(after: stringIndex)
            for row in 1 ... rows{
                let cell = Cell(col: colLetter, row: row, val: row)
                result.append((cell.coordinate,cell))
            }
        }while stringIndex != letter.endIndex
        var dataDic = [Coordinate:Cell]()
        for item in result{
            dataDic[item.0] = item.1
        }
        return dataDic
    }
    
}

